/* 
 * Copyright (c), nFractals Ltd. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.parade.driver.local;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

import org.parade.distributed.Id;


public class Driver extends org.parade.driver.Driver{
	AtomicLong idGenerator = new AtomicLong(0);
	
	Map<String, Object> oMap;

	
	public Driver(){
		throw new RuntimeException("This class is made for unittest. Can't be used in distributed environment");
	}
	
	public Driver(Map<String, Object> oMap){
		this.oMap = oMap;
	}
	
	@Override
	public Lock getLock(Id id) {
		synchronized(oMap){
			if(oMap.containsKey(id.toString())==false){
				Lock lock = new java.util.concurrent.locks.ReentrantLock();
				oMap.put(id.toString(), lock);
			}
			return (Lock) oMap.get(id.toString());
		}
	}

	@Override
	public long generateUniqueId() {
		return idGenerator.getAndIncrement();
	}

	@Override
	public Condition getCondition(org.parade.distributed.Lock lock) {
		synchronized(oMap){
			if(oMap.containsKey(lock.generateConditionObjectId().toString())==false){
				Lock lockObject = lock.getLockObject();
				Condition c = lockObject.newCondition();
				oMap.put(lock.generateConditionObjectId().toString(), c);
			}
			
			return (Condition) oMap.get(lock.generateConditionObjectId().toString());
		}
	}

	@SuppressWarnings("rawtypes")
	@Override
	public BlockingQueue getBlockingQueue(Id id) {
		synchronized(oMap){
			if(oMap.containsKey(id.toString())==false){
				BlockingQueue q = new LinkedBlockingQueue();
				oMap.put(id.toString(), q);
			}
			return (BlockingQueue) oMap.get(id.toString());
		}
	}

	@Override
	public Map getMap(Id id) {
		synchronized(oMap){
			if(oMap.containsKey(id.toString())==false){
				Map m = Collections.synchronizedMap(new LinkedHashMap());
				oMap.put(id.toString(), m);
			}
			return (Map) oMap.get(id.toString());
		}
	}

	



}
